package guhong.play.commandsystem;

import cn.hutool.core.exceptions.ExceptionUtil;
import cn.hutool.core.lang.Singleton;
import cn.hutool.core.util.ReflectUtil;
import cn.hutool.core.util.StrUtil;
import com.alibaba.fastjson.JSONObject;
import guhong.play.commandsystem.constant.Constant;
import guhong.play.commandsystem.dto.CommandDto;
import guhong.play.commandsystem.dto.entity.SystemConfig;
import guhong.play.commandsystem.exception.SystemException;
import guhong.play.commandsystem.gui.ui.UIManger;
import guhong.play.commandsystem.history.CommandHistoryManager;
import guhong.play.commandsystem.job.CommandJob;
import guhong.play.commandsystem.util.ToolUtil;
import guhong.play.commandsystem.util.file.FileOperationUtil;
import guhong.play.commandsystem.util.print.PrintUtil;
import lombok.Getter;

/**
 * 命令管理器
 *
 * @author : 李双凯
 * @date : 2019-11-20 22:32
 **/
public class CommandManager {


    /**
     * 系统配置对象
     */
    @Getter
    private static SystemConfig systemConfig = null;

    /**
     * 命令传输对象
     */
    @Getter
    private static CommandDto commandDto = null;

    @Getter
    private static CommandHistoryManager commandHistoryManager = Singleton.get(CommandHistoryManager.class);

    @Getter
    private static UIManger uiManger = Singleton.get(UIManger.class);

    private CommandManager() {
    }


    public static void execute(String commandStr) {
        try {
            String commandKey = getCommandKey(commandStr);
            if (null == commandKey) {
                return;
            }
            CommandJob commandJob = commandDto.getCommandJob(commandKey);
            if (null == commandJob) {
                commandKey = systemConfig.getDefaultCommand();
                if (StrUtil.isBlank(commandKey)) {
                    PrintUtil.printLnError("你输入的命令不存在，并且也没有设置默认命令！请检查命令是否正确或者通过[dc 命令名]设置默认命令！");
                    return;
                }
                commandStr = commandKey + " " + commandStr;
                commandJob = commandDto.getCommandJob(commandKey);
                if (null == commandJob) {
                    PrintUtil.printLnError("默认命令【" + commandKey + "】是一个不存在的命令Key，请检查！");
                    return;
                }
            }
            // 打印命令
            PrintUtil.println(ToolUtil.getHeadInfo() + commandStr);
            commandJob.doStart(commandStr);
        } catch (Exception e) {
            PrintUtil.printLnError("命令执行失败：" + ExceptionUtil.getRootCause(e).getMessage());
        } finally {
            commandHistoryManager.add(commandStr);
            commandHistoryManager.flush();
        }
    }


    /**
     * 获得命令名
     *
     * @param commandStr 命令字符串
     * @return 返回命令名
     */
    public static String getCommandKey(String commandStr) {
        if (StrUtil.isBlank(commandStr)) {
            return null;
        }
        commandStr = commandStr.trim();
        String[] split = commandStr.split("\\s+");
        String commandKey = split[0];
        if (StrUtil.isBlank(commandKey)) {
            return null;
        }
        return commandKey;
    }


    /**
     * 初始化
     */
    public static void init() {
        try {
            // 读取配置文件
            systemConfig = FileOperationUtil.readSystemConfig();
            if (null == systemConfig) {
                // 使用默认配置
                systemConfig = SystemConfig.buildDefaultConfig();
                // 将默认配置再存入配置文件
                FileOperationUtil.coverAppendConfig(Constant.SYSTEM_CONFIG_FILE, JSONObject.toJSONString(systemConfig));
                PrintUtil.warnPrint("读取配置文件失败，已使用默认配置！");
            }

            // 使用命令传输对象加载工作
            commandDto = ReflectUtil.newInstance(systemConfig.getDto());
            if (null == commandDto) {
                throw new SystemException("命令传输对象无法初始化，请检查配置！");
            }
            commandDto.load(null);

            // 执行命令的初始化
            for (CommandJob commandJob : commandDto.getCommandJobList(null)) {
                commandJob.windowOpened();
            }
        } catch (Exception e) {
            PrintUtil.printLnError("命令管理器初始化失败：" + e.getMessage());
        }
    }

    /**
     * 结束
     */
    public static void shutdown() {
        // 执行命令的结束回调
        for (CommandJob commandJob : commandDto.getCommandJobList(null)) {
            commandJob.windowClosing();
        }
        System.exit(0);
    }


}
